#include <iostream>
#include <assert.h>
#include <unistd.h>
#include <signal.h>

using std::cout;
using std::endl;

// // 捕捉所有信号
// void catchSig(int signum)
// {
//     cout << getpid() << " 获得了一个信号: "<< signum << endl;

//     switch(signum)
//     {
//         case SIGINT:
//             break;
//         case SIGQUIT:
//             break;
//     }
// }

// int main()
// {
//     for (int sig = 1; sig <= 31; sig++)
//     {
//         signal(sig, catchSig);
//     }

//     while(true) sleep(1);
//     return 0;
// }


// // 对2号信号进行阻塞,并解除阻塞
// static void handler(int signum)
// {
//     cout << "捕捉信号: " << signum << endl;
//     exit(1);
// }

// static void showPending(sigset_t& pending)
// {
//     for (int sig = 1; sig <= 31; sig++)
//     {
//         if (sigismember(&pending, sig))
//         {
//             cout << "1";
//         }
//         else
//         {
//             cout << "0";
//         }
//     }
//     cout << endl;
// }

// int main()
// {
//     signal(2, handler);

//     // 1.定义信号集对象
//     sigset_t bset, obset;
//     sigset_t pending;

//     // 2.初始化
//     sigemptyset(&bset);
//     sigemptyset(&obset);
//     sigemptyset(&pending);

//     // 3.添加要进行屏蔽的信号
//     sigaddset(&bset, 2);

//     // 4.设置set到内核中对应的进程内部  [默认任何情况不会对任何信号进行block]
//     int n = sigprocmask(SIG_BLOCK, &bset, &obset);
//     assert(n == 0);
//     (void)n;
//     cout << "block 2 号信号成功 ..." << getpid() << endl;

//     // 5.重复打印当前进程的pending信号集
//     int count = 0;
//     while (true)
//     {
//         // 5.1获取当前进程的pending信号集
//         sigpending(&pending);

//         // 5.2显示pending信号集中没有递达的信号
//         showPending(pending);
//         sleep(1);
//         count++;
//         if (count == 20)
//         {
//             // 恢复对2号信号的block时,是会进行递达
//             int n = sigprocmask(SIG_SETMASK, &obset, nullptr);
//             assert(n == 0);
//             (void) n;
//             cout << "解除对2号信号的block" << endl;
//         }
//     }

//     return 0;
// }


// // 阻塞所有的信号
// static void blockSig(int signum)
// {
//     sigset_t bset;
//     sigemptyset(&bset);
//     sigaddset(&bset, signum);
//     int n = sigprocmask(SIG_BLOCK, &bset, nullptr);
//     assert(n == 0);
//     (void)n;
// }

// static void showPending(sigset_t& pending)
// {
//     for (int sig = 0; sig <= 31; sig++)
//     {
//         if (sigismember(&pending, sig))
//         {
//             cout << "1";
//         }
//         else
//             cout << "0";
//     }
//     cout << endl;
// }

// int main()
// {
//     for (int sig = 1; sig <= 31; sig++)
//     {
//         blockSig(sig);
//     }
//     sigset_t pending;
//     while (true)
//     {
//         sigpending(&pending);
//         showPending(pending);
//         sleep(1);
//     }
// }


// // OS处理某信号时,再次收到该信号,会把外来的该信号直接阻塞,等这个信号处理完了,在解除阻塞
// void showPending(sigset_t& pending)
// {
//     for (int sig = 1; sig <= 31; sig++)
//     {
//         if (sigismember(&pending, sig))
//         {
//             cout << "1";
//         }
//         else
//             cout << "0";
//     }
//     cout << endl;
// }

// void handler(int signum)
// {
//     cout << "获得一个信号: " << signum << endl;
    
//     sigset_t pending;
//     int count = 20;
//     while (count-- > 0)
//     {
//         sigpending(&pending);
//         showPending(pending);
//         sleep(1);
//     }
// }

// int main()
// {
//     signal(SIGINT, handler);

//     while (true) sleep(1);
//     return 0;
// }



// // 子进程退出时,给父进程发送17号信号
// void handler(int signum)
// {
//     cout << "子进程退出: " << signum << " " << getpid() << endl;
// }
// int main()
// {
//     signal(SIGCHLD, handler);

//     if (fork() == 0)
//     {
//         cout << "pid: " << getpid() << endl;
//         sleep(1);
//         exit(0);
//     }

//     while (true) sleep(1);
//     return 0;
// }


// 信号忽略  把处理方法handler -> SIG_IGN  
// 不想等待子进程,让子进程结束后自己退出,并释放僵尸进程
int main()
{
    signal(SIGCHLD, SIG_IGN);   // 对17号信号进行信号忽略
    if (fork() == 0)
    {
        cout << "child: " << getpid() << endl;
        sleep(5);
        exit(1);
    }
    while (true)
    {
        cout << "parent: " << getpid() << " 执行我自己的任务!" << endl;
        sleep(1);
    }
    return 0;
}

